Skip to content

Conversation

@Ruakij
Copy link
Contributor

@Ruakij Ruakij commented May 26, 2025

Related GitHub Issue

Closes: #2325

Description

This PR adds protection against LLM-generated code edits that incorrectly duplicate closing braces and lines in MultiSearchReplace or ApplyDiff Tool.
e.g. when LLMs append methods to files using search/replace operations, they often include existing closing braces in the replacement content, leading to syntax errors from duplicated braces. The new system detects these patterns and automatically adjusts the replacement scope to prevent duplicate lines.

Key implementation details:

  • Added tests for common MultiSearchReplace scenarios
  • Implemented a new SuperfluousDuplicatedLineEngine to detect existing lines in the replacements not found in search
  • Integrated the new Engine-design into MultiSearchReplaceDiffStrategy to include SuperfluousDuplicatedLineEngine

Test Procedure

  1. Unit Tests:
  • Added tests multi-search-replace.test.ts covering:
    • Appending content while avoiding duplicate closing braces
    • Handling common line preservation
    • Edge cases with line similarity
  1. Manual Testing:
  • Test editing files via applyDiff

Type of Change

  • 🐛 Bug Fix: Non-breaking change that fixes an issue.
  • New Feature: Non-breaking change that adds functionality.
  • 💥 Breaking Change: Fix or feature that would cause existing functionality to not work as expected.
  • ♻️ Refactor: Code change that neither fixes a bug nor adds a feature.
  • 💅 Style: Changes that do not affect the meaning of the code (white-space, formatting, etc.).
  • 📚 Documentation: Updates to documentation files.
  • ⚙️ Build/CI: Changes to the build process or CI configuration.
  • 🧹 Chore: Other changes that don't modify src or test files.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue
  • Scope: Changes are focused on the line duplication bug fix
  • Self-Review: Performed thorough self-review of code
  • Code Quality:
    • Code adheres to project's style guidelines
    • No new linting errors/warnings
    • Debug code removed
  • Testing:
    • New tests added for line duplication scenarios
    • All tests pass locally
    • Application builds successfully
  • Branch Hygiene: Branch is up-to-date with main
  • Documentation Impact: No documentation updates required
  • Changeset: Not required as this is a bug fix
  • Contribution Guidelines: Read and followed guidelines

Screenshots / Videos

Documentation Updates

  • No documentation updates are required.
  • Yes, documentation updates are required.

Additional Notes

I have added a Modular approach to for such fixes to MultiSearchReplace for future issues
Some of the existing code could also be refactored into these Modules like Unescaping, Stripping Line numbers or other Error-checking.

I chose this approach because the file and function already is very big and complex.
If this is unwanted i could simply add my modification as function at the bottom instead.

Special consideration should be taken when testing the changes to make sure they dont break normal diffs on accident.

Get in Touch

Discord: ruakij


Important

Introduces SuperfluousDuplicatedLineEngine to handle duplicated lines in diffs, with integration and tests in multi-search-replace.ts.

  • Behavior:
    • Adds SuperfluousDuplicatedLineEngine to detect and adjust for duplicated lines in multi-search-replace.ts.
    • Integrates the engine into applyDiff() in multi-search-replace.ts to prevent duplicate lines during replacements.
  • Tests:
    • Adds tests in multi-search-replace.test.ts for scenarios like appending content without duplicating braces or lines, handling line similarity, and edge cases.
  • Misc:
    • Refactors applyDiff() to use SearchReplaceContext for better context management.

This description was created by Ellipsis for 54a09adcd34cbc6882c93edcc6093c855d13996d. You can customize this summary. It will automatically update as commits are pushed.

@Ruakij
Copy link
Contributor Author

Ruakij commented May 26, 2025

I have seen the closed PR #3411 which extracts the single apply diff into its own function, i think that could be a good addition for reducing complexity too.
Thoughts?

@Ruakij Ruakij force-pushed the feat/2325/Unclosed-parentheses-frequently-appear-during-editing branch from 54a09ad to 70203d0 Compare May 26, 2025 21:47
@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label May 27, 2025
@hannesrudolph hannesrudolph moved this from Triage to PR [Needs Preliminary Review] in Roo Code Roadmap May 28, 2025
@hannesrudolph hannesrudolph added PR - Needs Preliminary Review and removed Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. labels May 28, 2025
@Ruakij Ruakij force-pushed the feat/2325/Unclosed-parentheses-frequently-appear-during-editing branch from 70203d0 to b6d022a Compare May 29, 2025 12:21
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label May 29, 2025
@Ruakij Ruakij force-pushed the feat/2325/Unclosed-parentheses-frequently-appear-during-editing branch from b6d022a to 98b06ce Compare May 30, 2025 06:44
@vercel
Copy link

vercel bot commented May 30, 2025

@Ruakij is attempting to deploy a commit to the Roo Code Team on Vercel.

A member of the Team first needs to authorize it.

@Ruakij Ruakij force-pushed the feat/2325/Unclosed-parentheses-frequently-appear-during-editing branch from 98b06ce to 7af69b8 Compare May 31, 2025 08:46
@Ruakij Ruakij force-pushed the feat/2325/Unclosed-parentheses-frequently-appear-during-editing branch from 7af69b8 to 42879fb Compare June 5, 2025 09:12
@daniel-lxs
Copy link
Member

daniel-lxs commented Jun 5, 2025

Hey @Ruakij, thanks for working on this! I've been looking through the changes and I appreciate the modular approach you've taken.

I'm a bit concerned though - this feels like quite a complex solution for something that mainly affects DeepSeek models (DeepSeek R1 to be more specific). The engine adds processing to every search/replace operation, and I worry it might interfere with cases where someone actually wants to duplicate similar code patterns.

Since the root issue seems to be that certain LLMs include existing closing braces in their replacements, what do you think about trying something simpler first? Maybe we could improve the prompts for those specific models, or add a quick check that warns when a replacement would create syntax errors?

I'm curious if you considered any lighter-weight approaches before going with the engine solution? Would love to hear your thoughts on this!

@daniel-lxs daniel-lxs moved this from PR [Needs Prelim Review] to PR [Changes Requested] in Roo Code Roadmap Jun 5, 2025
@Ruakij
Copy link
Contributor Author

Ruakij commented Jun 6, 2025

I think there is always a danger when trying to fix issues some LLMs might have or how their behaviour is. I have had this replacement issue with Sonnet models multiple times now too.
When writing code they are trained to rather complete the block properly rather than following the overall high-level structure. This is therefore probably an issue for any structured output they generate.

My approach is pretty primitive, but should cover most scenarios, as long as replacement lines arent similar on purpose. Not 100% sure how to detect that reliably.

For structured languages with grammar-rules we can parse, at least we can detect if either the LLM or our fix made a mistake, so if we really want to keep the fix broad but reduce errors, the ideal approach would be to parse the result first and check if syntax errors were introduced at the edges.
Though this would require introducing a parsing step ourselves, something the IDE will most likely already run. Quite complex stuff to handle.
If we truly want auto-fixing, this can be done in limited capacity with heuristics, but for catching other errors it could be better to use an apply-diff-model like some others.

So for now, maybe keeping the SuperfluousDuplicatedLineEngine is okay, but adding some checks so we dont accidentally touch stuff we didnt want "fixed". e.g. We only consider lines "similar" if they have at least 3 characters (including spaces), but we wont apply any fixes when we find more than 2 similar lines. (or % of output)
Currently we would cut off any similar lines, no matter what they are (ignoring spaces) or how many.

@daniel-lxs
Copy link
Member

@Ruakij
What we want to avoid is to add checks and guardrails for every problem and quirk a model might have, it's better to first explore minimal changes, changes to the way the tool is described, basically attack the root problem rather than trying to attack the symptoms.

Checking every apply_diff just to see if a single { is left behind seems like a bit of a waste, specially since we are always improving our system prompt and models get better at following instructions, making our guardrails obsolete.

I'll close this PR for now but that doesn't mean I am not open to discussing this further, please let me know what you think!

@daniel-lxs daniel-lxs closed this Jun 6, 2025
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Jun 6, 2025
@github-project-automation github-project-automation bot moved this from PR [Changes Requested] to Done in Roo Code Roadmap Jun 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR - Changes Requested size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Unclosed parentheses frequently appear during editing

3 participants